/*
 * Copyright 2003 Program of Computer Graphics, Cornell University
 *     580 Rhodes Hall
 *     Cornell University
 *     Ithaca NY 14853
 * Web: http://www.graphics.cornell.edu/
 * 
 * Not for commercial use. Do not redistribute without permission.
 */

#ifndef _H_SCENE
#define _H_SCENE

#include "Geometry.h"
#include "KDTree.h"

class Scene {
  //pool of initial (uncompiled) geometry objects
  PoolAllocator *geomPool;
  //set of initial geometry objects
  GeometrySet *full;
  //kdtree compiled ray acceleration structure once it has been built 
  KDTree *tree;
public:
  Scene() { full = NULL; tree = NULL; geomPool = new PoolAllocator(POOL_SEGMENT_SIZE,sizeof(float)); }
  ~Scene();

  PoolAllocator *getGeometryObjectPool() { return geomPool; }
  GeometrySet *getAllGeometrySet() { return full; }
  void addGeometryObject(GeometryObject *obj);
  void deleteUncompiledGeometry() {  //does not remove the compiled kdtree
    if (full) { full->removeAll(); delete full; full = NULL; }
    if (geomPool) { geomPool->deallocateAll(); }
  }
  void buildFlatList();
  void buildNaiveMiddleSplit(int depth);
  void buildNaiveMedianSplit(int maxElementsPerLeaf);
  void buildGreedySplit();
  void deleteAll() { 
    if (full) { full->removeAll(); delete full; full = NULL; }
    if (geomPool) { geomPool->deallocateAll(); }
    if (tree) { delete tree; tree = NULL; }
  }
  void intersect(const Ray &ray, IntersectionRecord *hitRec) { 
//    unsigned int oldMode = sseSetDAZMode(); //turns out to be quite expensive to set sse mode
    tree->intersect(ray,hitRec); 
//    sseRestoreMode(oldMode);
  }
  void intersect(int numRays, const Ray ray[4], IntersectionRecord hitRec[4]) {
    tree->intersect(numRays,ray,hitRec);
  }
  AxisAlignedBox getBoundingBox() {
    return tree->getBiggerBounds(); 
  }

  void printTreeStats()
  { tree->printTreeStatistics(); }
//  { full->debug_intersect_all(ray,hitRec); }
};


#endif //_H_SCENE
